package com.sj.filter;

import cn.hutool.core.util.StrUtil;
import com.sj.security.SecurityUser;
import com.sj.security.UserDetailServiceImpl;
import com.sj.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

/**
 * Created with IntelliJ IDEA.
 * User: xiaoqi
 * Date: 2022-03-11
 * Time: 上午 8:50
 * Description: Jwt过滤器
 *
 * @author xiaoqi
 * @since 2022-03-11
 */
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private UserDetailServiceImpl userDetailService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 如果请求头没有token 该请求是否需要token就不清楚，交给后面处理，直接放行
        String bearerToken = request.getHeader(jwtUtils.getHeader());
        if (StrUtil.isBlankOrUndefined(bearerToken)) {
            chain.doFilter(request, response);
            return;
        }

        // 如果携带token 那么判断该token是否有效
        String[] tokens = bearerToken.split(" ");
        Claims claims = jwtUtils.checkToken(request);
        if (claims != null) {
            String[] userInfo = claims.getSubject().split("-");
            // 获取用户权限信息
            Integer uId = Integer.parseInt(userInfo[0]);
            Collection<? extends GrantedAuthority> authorities = userDetailService.getAuthorities(uId, userInfo[1]);
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userInfo[1], null, authorities);
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        }
        chain.doFilter(request, response);
    }

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }
}